/*
 * edbd_cmd.c - EDB command processing part
 * Clunix, cezanne@clunix.com, 2005.3
 *
 * Copyright (c) 2001-2005 by Clunix Inc. All Rights Reserved.
 */

#include "config.h"

#include "edbd.h"
#include "reactor.h"
#include "bdexpr.h"
#include "eds.h"
#include "edbroot.h"
#include "edbsr.h"

struct xename_srt_info {
	const char	*name;
	srt_t		srt;
};

ECM_INLINE edb_err_t
do_all_child_ptrs(edbd_conn_t edbd_conn, sr_t *sr_ptrs, executer_t executer, ecm_ptr_t ctx, sr_t **psr_res)
{
	sr_t	*sr_ptr, *sr_child;
	sr_t	*sr_res, *sr_res_one;
	ECMBOOL	onlyone = ECM_FALSE;
	int	num_child;
	edb_err_t	err = EDB_OK;

	if (psr_res)
		*psr_res = NULL;

	if ((num_child = sr_get_num_child(sr_ptrs)) <= 0) {
		sr_free(sr_ptrs);
		return -ERR_EDB_NOTEXIST;
	}

	if (num_child == 1)
		onlyone = ECM_TRUE;

	sr_res = sr_create_dir();
	SR_FOREACH_CHILD(sr_ptrs, NULL, sr_ptr) {
		sr_child = (sr_t *)sr_get_ptr(sr_ptr);

		if ((err = executer(edbd_conn, sr_child, &sr_res_one, ctx, onlyone)) != EDB_OK)
			break;
		sr_append(sr_res, sr_res_one);
	}

	tree_unlock_ptrs(sr_ptrs, PIN_LOCK);
	sr_free(sr_ptrs);

	if (err == EDB_OK) {
		if (psr_res)
			*psr_res = sr_res;
		return EDB_OK;
	}
	sr_free(sr_res);
	return err;
}

edb_err_t
create_sr(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t		*sr_new;
	edb_err_t	err;
	sr_new = (onlyone) ? sr_crop((sr_t *)ctx) : sr_dup((sr_t *)ctx);

	err = conn_append(edbd_conn, sr, sr_new, ECM_TRUE);
	if (err != EDB_OK)
		sr_free(sr_new);
	*psr_res = NULL;

	return err;
}

edb_err_t
rename_sr(edbd_conn_t conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_set_name(sr, (char *)ctx);
	*psr_res = NULL;

	return EDB_OK;
}

sr_walk_res_t
copy_val_walk(sr_t *sr_dst, sr_t *sr_src, ecm_ptr_t ctx)
{
	sr_val_t	val;

	if (sr_is_group(sr_dst))
		return SR_WALK_OK;

	if (edbroot_get_val((edbd_conn_t)ctx, sr_src, &val) != EDB_OK)
		return SR_WALK_FAILED;

	if (sr_set_val(sr_dst, val))
		return SR_WALK_OK;
	srv_free(sr_src->type, val);
	return SR_WALK_FAILED;
}

static ECM_INLINE sr_walk_res_t
set_owner_walk(sr_t *sr_dst, sr_t *sr_src, ecm_ptr_t ctx)
{
	eds_set_owner(sr_dst, eds_get_owner(sr_src));
	return SR_WALK_OK;
}

static ECM_INLINE sr_walk_res_t
set_user_walk(sr_t *sr_dst, sr_t *sr_src, ecm_ptr_t ctx)
{
	eds_set_user(sr_dst, eds_get_user(sr_src));
	return SR_WALK_OK;
}

static ECM_INLINE sr_walk_res_t
set_group_walk(sr_t *sr_dst, sr_t *sr_src, ecm_ptr_t ctx)
{
	eds_set_group(sr_dst, eds_get_group(sr_src));
	return SR_WALK_OK;
}

static ECM_INLINE sr_walk_res_t
set_perm_walk(sr_t *sr_dst, sr_t *sr_src, ecm_ptr_t ctx)
{
	eds_set_perm(sr_dst, eds_get_perm(sr_src));
	return SR_WALK_OK;
}

static ECM_INLINE sr_walk_res_t
set_attr_update_walk(sr_t *sr_dst, sr_t *sr_src, ecm_ptr_t ctx)
{
	eds_set_attr_update(sr_dst, eds_get_attr_update(sr_src));
	return SR_WALK_OK;
}

static ECM_INLINE sr_walk_res_t
set_attr_fetch_walk(sr_t *sr_dst, sr_t *sr_src, ecm_ptr_t ctx)
{
	eds_set_attr_fetch(sr_dst, eds_get_attr_fetch(sr_src));
	return SR_WALK_OK;
}

static ECM_INLINE sr_walk_res_t
set_attr_system_walk(sr_t *sr_dst, sr_t *sr_src, ecm_ptr_t ctx)
{
	eds_set_attr_system(sr_dst, eds_get_attr_system(sr_src));
	return SR_WALK_OK;
}

static ECM_INLINE sr_walk_res_t
set_reactor_walk(sr_t *sr_dst, sr_t *sr_src, ecm_ptr_t ctx)
{
	eds_set_reactors(sr_dst, eds_get_reactors(sr_src));
	return SR_WALK_OK;
}

static edbd_walkopt_t
applyopt_to_walkopt(int applyopt)
{
	edbd_walkopt_t	walkopt = 0;
	if (applyopt & SR_RECUR)
		walkopt |= EDBD_WALKOPT_RECUR;
	if (applyopt & SR_NO_DEREF)
		walkopt |= EDBD_WALKOPT_NO_DEREF;
	if (applyopt & SR_NOT_THIS)
		walkopt |= EDBD_WALKOPT_NOT_THIS;
	return walkopt;
}

static edb_err_t
get_sr_val(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t	*sr_res;
	int	applyopt = (int)(ecm_iptr_t)ctx;

	sr_res = edbd_walk_dup(sr, copy_val_walk, edbd_conn, applyopt_to_walkopt(applyopt));
	if (sr_res == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_res;

	if (applyopt & EDB_OPT_CHGDIR) {
		sr_t	*sr_cwd;

		if (sr_is_group(sr))
			sr_cwd = sr;
		else
			sr_cwd = sr->parent;
		edbd_conn_setcwd(edbd_conn, sr_cwd);
	}

	return EDB_OK;
}

static edb_err_t
get_sr_owner(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t	*sr_res;
	int	applyopt = (int)(ecm_iptr_t)ctx;

	sr_res = edbd_walk_dup(sr, set_owner_walk, NULL, applyopt_to_walkopt(applyopt));
	if (sr_res == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_res;
	return EDB_OK;
}

static edb_err_t
get_sr_user(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t	*sr_res;
	int	applyopt = (int)(ecm_iptr_t)ctx;

	sr_res = edbd_walk_dup(sr, set_user_walk, NULL, applyopt_to_walkopt(applyopt));
	if (sr_res == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_res;
	return EDB_OK;
}

static edb_err_t
get_sr_group(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t	*sr_res;
	int	applyopt = (int)(ecm_iptr_t)ctx;

	sr_res = edbd_walk_dup(sr, set_group_walk, NULL, applyopt_to_walkopt(applyopt));
	if (sr_res == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_res;
	return EDB_OK;
}

static edb_err_t
get_sr_perm(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t	*sr_res;
	int	applyopt = (int)(ecm_iptr_t)ctx;

	sr_res = edbd_walk_dup(sr, set_perm_walk, NULL, applyopt_to_walkopt(applyopt));
	if (sr_res == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_res;
	return EDB_OK;
}

static edb_err_t
get_sr_attr_update(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t	*sr_res;
	int	applyopt = (int)(ecm_iptr_t)ctx;

	sr_res = edbd_walk_dup(sr, set_attr_update_walk, NULL, applyopt);
	if (sr_res == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_res;
	return EDB_OK;
}

static edb_err_t
get_sr_attr_fetch(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t	*sr_res;
	int	applyopt = (int)(ecm_iptr_t)ctx;

	sr_res = edbd_walk_dup(sr, set_attr_fetch_walk, NULL, applyopt_to_walkopt(applyopt));
	if (sr_res == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_res;
	return EDB_OK;
}

static edb_err_t
get_sr_attr_system(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t	*sr_res;
	int	applyopt = (int)(ecm_iptr_t)ctx;

	sr_res = edbd_walk_dup(sr, set_attr_system_walk, NULL, applyopt_to_walkopt(applyopt));
	if (sr_res == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_res;
	return EDB_OK;
}

static edb_err_t
get_sr_reactor(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t	*sr_res;
	int	applyopt = (int)(ecm_iptr_t)ctx;

	sr_res = edbd_walk_dup(sr, set_reactor_walk, NULL, applyopt_to_walkopt(applyopt));
	if (sr_res == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_res;
	return EDB_OK;
}

static edb_err_t
set_sr_with_asrv(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	const char	*casrv = (const char *)ctx;
	edb_err_t	err;

	err = conn_set_asrv(edbd_conn, sr, casrv);
	*psr_res = NULL;
	return err;
}

static edb_err_t
set_sr(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	sr_t		*sr_operand = sr_dup((sr_t *)ctx);
	edb_err_t	err;

	if ((err = conn_set_sr(edbd_conn, sr, sr_operand, ECM_TRUE)) != EDB_OK)
		sr_free(sr_operand);
	*psr_res = NULL;
	return err;
}

static edb_err_t
set_sr_owner(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	*psr_res = NULL;
	return edbroot_set_owner(edbd_conn, sr, *(xid_t *)ctx);
}

static edb_err_t
set_sr_user(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	*psr_res = NULL;
	return edbroot_set_user(edbd_conn, sr, (const char *)ctx);
}

static edb_err_t
set_sr_group(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	*psr_res = NULL;
	return edbroot_set_group(edbd_conn, sr, (const char *)ctx);
}

static edb_err_t
set_sr_perm(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	*psr_res = NULL;
	return edbroot_set_perm(edbd_conn, sr, *(eds_perm_t *)ctx);
}

static edb_err_t
set_sr_attr_update(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	*psr_res = NULL;
	return edbroot_set_attr_update(edbd_conn, sr, *(ecm_uint32 *)ctx);
}

static edb_err_t
set_sr_attr_fetch(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	*psr_res = NULL;
	return edbroot_set_attr_fetch(edbd_conn, sr, *(ecm_uint32 *)ctx);
}

static edb_err_t
set_sr_reactor(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	const char	*edexpr = (char *)ctx;
	sr_t		*sr_edexprs;
	edb_err_t	err;

	if (ecm_empty_str(edexpr))
		sr_edexprs = NULL;
	else {
		sr_edexprs = edl_get_edexpr(edexpr, NULL, NULL);
		if (sr_edexprs == NULL)
			return -ERR_EDB_WRONGEDEXPR;
	}

	err = conn_set_reactors(edbd_conn, sr, sr_edexprs);
	sr_free(sr_edexprs);

	*psr_res = NULL;
	return err;
}

static edb_err_t
del_sr(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	int		applyopt = (int)(ecm_iptr_t)ctx;
	edb_err_t	err;

	if (sr_is_group(sr)) {
		if (!(SR_RECUR & applyopt) && sr_get_num_child(sr) > 0)
			return -ERR_EDB_EXIST;
	}
	err = conn_edbroot_del(edbd_conn, sr, ECM_TRUE, ECM_TRUE);
	*psr_res = NULL;
	return err;
}

static edb_err_t
change_cwd(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	char	*cwd;

	if (!onlyone)
		return -ERR_EDB_GENERAL;
	edbd_conn_setcwd(edbd_conn, sr);
	cwd = sr_get_LNP(sr);

	*psr_res = sr_create_val(ST_STR, sr_val_str(cwd));
	return EDB_OK;
}

static edb_err_t
shutdown_edbd(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	*psr_res = NULL;
	return edbd_shutdown(edbd_conn, sr);
}

static edb_err_t
create_xe(edbd_conn_t edbd_conn, sr_t *sr, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	struct xename_srt_info	*info = (struct xename_srt_info *)ctx;
	sr_t	*sr_xe;

	sr_xe = conn_xecreate(edbd_conn, sr, info->name, info->srt, 0, ECM_TRUE);
	if (sr_xe == NULL)
		return -ERR_EDB_GENERAL;
	*psr_res = sr_create_str(ST_STR, sr_get_name(sr_xe));
	tree_unlock(sr_xe, PIN_LOCK);
	return EDB_OK;
}

static edb_err_t
delete_xe(edbd_conn_t edbd_conn, sr_t *sr_xe, sr_t **psr_res, ecm_ptr_t ctx, ECMBOOL onlyone)
{
	edb_err_t	err;

	if ((err = conn_xedelete(edbd_conn, sr_xe, ECM_TRUE, (ECMBOOL)ctx)) != EDB_OK)
		return err;
	*psr_res = NULL;
	return EDB_OK;
}

edb_err_t
do_cmd_create(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t	*sr_LNP, *sr_new, *sr_lastLNI;
	const char	*edexpr;
	sr_t	*sr_traversed;
	sr_t	*sr_ret;

	const char	*newname;
	edb_err_t	err;

	EDBDDBG(DBG_CLIREQ, "CMD_CREATE");

	sr_new = sr_geti(sr_cmd, 1);
	sr_LNP = sr_geti(sr_cmd, 2);
	edexpr = sr_geti_str(sr_cmd, 3);
	sr_lastLNI = sr_get_last(sr_get_child(sr_LNP, "LNIs"));

	if (sr_getc_int(sr_lastLNI, "Type") != LNI_TYPE_NAME ||
	    (newname = sr_getc_str(sr_lastLNI, "Name")) == NULL)
		return -ERR_EDB_INVALIDLNP;

	err = traverse_tree(edbd_conn, sr_LNP, edexpr, &sr_traversed,
			    SR_TRAV_CREATE | SR_TRAV_GETPARENT | SR_TRAV_ABSENTONLY);
	if (err < 0)
		return err;
	sr_set_name(sr_new, newname);
	err = do_all_child_ptrs(edbd_conn, sr_traversed, create_sr, sr_new, &sr_ret);

	if (err < 0)
		return err;

	sr_free(sr_ret);
	
	EDBDDBG(DBG_CLIREQ, "creation success");

	*psr_res = NULL;
	return EDB_OK;
}

edb_err_t
do_cmd_get(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t	*sr_LNP;
	sr_t	*sr_traversed, *sr_res;
	sr_travopt_t	travopt = 0;
	const char	*edexpr;
	long		opt;
	edb_field_t	field;
	executer_t	executer;
	edb_err_t	err;

	opt = sr_geti_int(sr_cmd, 1);
	field = sr_geti_int(sr_cmd, 2);
	sr_LNP = sr_geti(sr_cmd, 3);
	edexpr = sr_geti_str(sr_cmd, 4);

	EDBDDBG(DBG_CLIREQ, "CMD_GET_SR: %s, %s, %s, [%s]",
		dbg_get_LNP(sr_LNP),
		dbg_get_opt(opt),
		dbg_get_field(field),
		ecm_safe_str(edexpr));

	if (opt & SR_NO_DEREF)
		travopt = SR_TRAV_NO_DEREF;

	err = traverse_tree(edbd_conn, sr_LNP, edexpr, &sr_traversed, travopt);
	if (err < 0)
		return err;

	switch (field) {
	case EDB_FIELD_VAL:
		executer = get_sr_val;
		break;
	case EDB_FIELD_OWNER:
		executer = get_sr_owner;
		break;
	case EDB_FIELD_USER:
		executer = get_sr_user;
		break;
	case EDB_FIELD_GROUP:
		executer = get_sr_group;
		break;
	case EDB_FIELD_PERM:
		executer = get_sr_perm;
		break;
	case EDB_FIELD_ATTR_UPDATE:
		executer = get_sr_attr_update;
		break;
	case EDB_FIELD_ATTR_FETCH:
		executer = get_sr_attr_fetch;
		break;
	case EDB_FIELD_ATTR_SYSTEM:
		executer = get_sr_attr_system;
		break;
	case EDB_FIELD_REACTOR:
		executer = get_sr_reactor;
		break;
	default:
		return -ERR_EDB_GENERAL;
	}

	err = do_all_child_ptrs(edbd_conn, sr_traversed, executer, (ecm_ptr_t)(ecm_iptr_t)opt, &sr_res);
	if (err < 0)
		return err;

	*psr_res = sr_res;
	return EDB_OK;
}

edb_err_t
do_cmd_set(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t		*sr_LNP;
	sr_t		*sr_traversed, *sr_res;
	int		applyopt;
	sr_travopt_t	travopt = 0;
	edb_field_t	field;
	const char	*edexpr, *asrv;
	sr_val_t	srv;
	edb_err_t	err;

	field = sr_geti_int(sr_cmd, 1);
	applyopt = sr_geti_int(sr_cmd, 2);
	asrv = sr_geti_str(sr_cmd, 3);
	sr_LNP = sr_geti(sr_cmd, 4);
	edexpr = sr_geti_str(sr_cmd, 5);

	EDBDDBG(DBG_CLIREQ, "CMD_SET: %s %s %s %s",
		dbg_get_LNP(sr_LNP),
		dbg_get_opt(applyopt),
		dbg_get_field(field),
		asrv);

	if (applyopt & SR_NO_DEREF) {
		travopt = SR_TRAV_NO_DEREF;
	}
	err = traverse_tree(edbd_conn, sr_LNP, edexpr, &sr_traversed, travopt);
	if (err < 0)
		return err;

	switch (field) {
	case EDB_FIELD_VAL:
		err = do_all_child_ptrs(edbd_conn, sr_traversed, set_sr_with_asrv,
					(ecm_ptr_t)asrv, &sr_res);
		break;
	case EDB_FIELD_REACTOR:
		err = do_all_child_ptrs(edbd_conn, sr_traversed, set_sr_reactor, (ecm_ptr_t)asrv, &sr_res);
		break;
	case EDB_FIELD_OWNER:
		if (!sr_casrv_scan(asrv, ST_XID, &srv))
			return -ERR_EDB_WRONGASRV;
		err = do_all_child_ptrs(edbd_conn, sr_traversed, set_sr_owner, &srv.lval, &sr_res);
		break;
	case EDB_FIELD_USER:
		if (!sr_casrv_scan(asrv, ST_STR, &srv))
			return -ERR_EDB_WRONGASRV;
		err = do_all_child_ptrs(edbd_conn, sr_traversed, set_sr_user, srv.str, &sr_res);
		break;
	case EDB_FIELD_GROUP:
		if (!sr_casrv_scan(asrv, ST_STR, &srv))
			return -ERR_EDB_WRONGASRV;
		err = do_all_child_ptrs(edbd_conn, sr_traversed, set_sr_group, srv.str, &sr_res);
		break;
	case EDB_FIELD_PERM:
		if (!sr_casrv_scan(asrv, ST_PERM, &srv))
			return -ERR_EDB_WRONGASRV;
		err = do_all_child_ptrs(edbd_conn, sr_traversed, set_sr_perm, &srv.ival, &sr_res);
		break;
	case EDB_FIELD_ATTR_UPDATE:
		if (!sr_casrv_scan(asrv, ST_ATTR_UPDATE, &srv))
			return -ERR_EDB_WRONGASRV;
		err = do_all_child_ptrs(edbd_conn, sr_traversed, set_sr_attr_update, &srv.ival, &sr_res);
		break;
	case EDB_FIELD_ATTR_FETCH:
		if (!sr_casrv_scan(asrv, ST_ATTR_FETCH, &srv))
			return -ERR_EDB_WRONGASRV;
		err = do_all_child_ptrs(edbd_conn, sr_traversed, set_sr_attr_fetch, &srv.ival, &sr_res);
		break;
	case EDB_FIELD_ATTR_SYSTEM:
		sr_free(sr_traversed);
		return -ERR_EDB_NOTALLOWED;
	default:
		sr_free(sr_traversed);
		return -ERR_EDB_WRONGFIELD;
	}
	if (err < 0)
		return err;
	sr_free(sr_res);
	*psr_res = NULL;
	return EDB_OK;
}

edb_err_t
do_cmd_set_sr(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t		*sr_LNP, *sr_arg;
	sr_t		*sr_traversed, *sr_res;
	const char	*edexpr;
	int		applyopt;
	edb_field_t	field;
	executer_t	executer;
	edb_err_t	err;

	EDBDDBG(DBG_CLIREQ, "CMD_SET_SR");

	field = sr_geti_int(sr_cmd, 1);
	applyopt = sr_geti_int(sr_cmd, 2);
	sr_arg = sr_geti(sr_cmd, 3);
	sr_LNP = sr_geti(sr_cmd, 4);
	edexpr = sr_geti_str(sr_cmd, 5);

	err = traverse_tree(edbd_conn, sr_LNP, edexpr, &sr_traversed, 0);
	if (err < 0)
		return err;

	switch (field) {
	case EDB_FIELD_VAL:
		executer = set_sr;
		break;
	default:
		return -ERR_EDB_GENERAL;
	}

	err = do_all_child_ptrs(edbd_conn, sr_traversed, executer, (ecm_ptr_t)sr_arg, &sr_res);
	if (err < 0)
		return err;
	sr_free(sr_res);
	*psr_res = NULL;
	return EDB_OK;
}

edb_err_t
do_cmd_del(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t	*sr_LNP;
	sr_t	*sr_traversed, *sr_res;
	const char	*edexpr;
	long	opt;
	sr_travopt_t	travopt = 0;
	edb_err_t	err;

	EDBDDBG(DBG_CLIREQ, "CMD_DEL");

	opt = sr_geti_int(sr_cmd, 1);
	sr_LNP = sr_geti(sr_cmd, 2);
	edexpr = sr_geti_str(sr_cmd, 3);

	if (opt & SR_NO_DEREF)
		travopt = SR_TRAV_NO_DEREF;

	err = traverse_tree(edbd_conn, sr_LNP, edexpr, &sr_traversed, travopt);
	if (err < 0)
		return err;

	err = do_all_child_ptrs(edbd_conn, sr_traversed, del_sr, (ecm_ptr_t)(ecm_iptr_t)opt, &sr_res);
	if (err < 0)
		return err;
	sr_free(sr_res);
	*psr_res = NULL;
	return EDB_OK;
}

static edb_err_t
do_cmd_xecreate(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t	*sr_LNP, *sr_ret;
	sr_t	*sr_traversed;
	const char	*name, *srtstr, *edexpr;
	srt_t		srt = ST_NULL;
	struct xename_srt_info	info;
	edb_err_t	err;
	
	name = sr_geti_str(sr_cmd, 1);
	srtstr = sr_geti_str(sr_cmd, 2);
	sr_LNP = sr_geti(sr_cmd, 3);
	edexpr = sr_geti_str(sr_cmd, 4);

	EDBDDBG(DBG_CLIREQ, "CMD_XECREATE: %s %s %s", dbg_get_LNP(sr_LNP), ecm_safe_str(name), ecm_safe_str(srtstr));

	err = traverse_tree(edbd_conn, sr_LNP, edexpr, &sr_traversed, 0);

	if (err < 0)
		return -ERR_EDB_GENERAL;

	if (srtstr && !sr_search_srt(srtstr, &srt))
		return -ERR_EDB_WRONGSRT;
	info.name = name;
	info.srt = srt;
	err = do_all_child_ptrs(edbd_conn, sr_traversed, create_xe, (ecm_ptr_t)&info, &sr_ret);
	if (err < 0)
		return err;

	EDBDDBG(DBG_CLIREQ, "XE successfully created.");

	*psr_res = sr_ret;
	return EDB_OK;
}

static edb_err_t
do_cmd_xedelete(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t		*sr_LNP, *sr_ret;
	sr_t		*sr_traversed;
	const char	*edexpr;
	ECMBOOL		force;
	edb_err_t	err;

	force = sr_geti_bool(sr_cmd, 1);
	sr_LNP = sr_geti(sr_cmd, 2);
	edexpr = sr_geti_str(sr_cmd, 3);

	EDBDDBG(DBG_CLIREQ, "CMD_XEDELETE: %s with %s %d",
		dbg_get_LNP(sr_LNP),
		ecm_safe_str(edexpr),
		force);

	err = traverse_tree(edbd_conn, sr_LNP, edexpr, &sr_traversed, 0);
	if (err < 0)
		return err;

	err = do_all_child_ptrs(edbd_conn, sr_traversed, delete_xe, (ecm_ptr_t)force, &sr_ret);
	if (err < 0)
		return err;

	sr_free(sr_ret);
	EDBDDBG(DBG_CLIREQ, "XE successfully deleted");

	*psr_res = NULL;
	return EDB_OK;
}

static edb_err_t
do_cmd_cd(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t		*sr_traversed;
	sr_t		*sr_LNP;
	const char	*edexpr;
	sr_t		*sr_ret;
	edb_err_t	err;

	sr_LNP = sr_geti(sr_cmd, 1);
	edexpr = sr_geti_str(sr_cmd, 2);

	EDBDDBG(DBG_CLIREQ, "CMD_CD: %s with %s",
		dbg_get_LNP(sr_LNP),
		ecm_safe_str(edexpr));

	err = traverse_tree(edbd_conn, sr_LNP, edexpr, &sr_traversed, SR_TRAV_DIRONLY);
	if (err < 0)
		return err;
	err = do_all_child_ptrs(edbd_conn, sr_traversed, change_cwd, NULL, &sr_ret);
	if (err < 0)
		return err;
	*psr_res = sr_crop_first(sr_ret);
	sr_free(sr_ret);
	return err;
}

static edb_err_t
do_cmd_get_modinfos(edbd_conn_t edbd_conn, sr_t **psr_res)
{
	extern sr_t *get_modinfos(void);

	EDBDDBG(DBG_CLIREQ, "GET_MODINFOS");

	*psr_res = get_modinfos();
	return EDB_OK;
}

static edb_err_t
do_cmd_shutdown(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t		*sr_LNP;
	sr_t		*sr_traversed, *sr_ret;
	edb_err_t	err;

	sr_LNP = sr_geti(sr_cmd, 1);

	EDBDDBG(DBG_CLIREQ, "trying to shutdown [%s]", dbg_get_LNP(sr_LNP));

	if (sr_LNP) {
		err = traverse_tree(edbd_conn, sr_LNP, NULL, &sr_traversed, SR_TRAV_DIRONLY);
		if (err < 0)
			return err;
		err = do_all_child_ptrs(edbd_conn, sr_traversed, shutdown_edbd, NULL, &sr_ret);
		if (err < 0)
			return err;
		sr_free(sr_ret);
	}
	else
		err = edbd_shutdown(edbd_conn, NULL);

	*psr_res = NULL;
	return err;
}

edb_err_t
do_cmd_snapshot(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	if (!IS_MASTER())
		return -ERR_EDB_NOTMASTER;

	if (edbd_take_snapshot()) {
		*psr_res = NULL;
		return EDB_OK;
	}
	return -ERR_EDB_GENERAL;
}

static edb_err_t
do_cmd_get_typename(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t		*sr_req;
	const char	*srt_str;

	sr_req = sr_geti(sr_cmd, 1);
	srt_str = srt_get_name(sr_get_type(sr_req));

	EDBDDBG(DBG_CLIREQ, "CMD_GET_TYPENAME: %s", ecm_safe_str(srt_str));

	if (srt_str == NULL)
		return -ERR_EDB_NOTEXIST;

	*psr_res = sr_create_str(ST_STR, srt_str);
	return EDB_OK;
}

edb_err_t
do_cmd_get_inherited_srts(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	srt_t		srt_super;
	sr_t		*sr_srts;

	EDBDDBG(DBG_CLIREQ, "CMD_GET_INHERITED_SRTS");

	srt_super = sr_geti_type(sr_cmd, 1);

	sr_srts = srt_get_inherited_srts(srt_super);
	if (sr_srts == NULL)
		return -ERR_EDB_GENERAL;
	if (sr_get_num_child(sr_srts) <= 0) {
		sr_free(sr_srts);
		return -ERR_EDB_NOTEXIST;
	}
	*psr_res = sr_srts;
	return EDB_OK;
}

edb_err_t
do_cmd_search_srt(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	const char	*srtstr;
	srt_t		srt;

	EDBDDBG(DBG_CLIREQ, "CMD_SEARCH_SRT");

	srtstr = sr_geti_str(sr_cmd, 1);
	if (!sr_search_srt(srtstr, &srt))
		return -ERR_EDB_NOTEXIST;
	*psr_res = sr_create_int(ST_SRT, srt);
	return EDB_OK;
}

edb_err_t
do_cmd_close(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	EDBDDBG(DBG_CLIREQ, "CMD_CLOSE");

	edbd_conn_invalidate(edbd_conn);
	*psr_res = NULL;
	return EDB_OK;
}

static edb_err_t
do_cmd_get_asrv(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t	*sr_req, *sr_ret;
	char	*asrv;

	EDBDDBG(DBG_CLIREQ, "CMD_GET_ASRV");

	sr_req = sr_geti(sr_cmd, 1);
	if (sr_req == NULL)
		return -ERR_EDB_GENERAL;

	asrv = sr_get_asrv(sr_req);
	if (asrv == NULL)
		return -ERR_EDB_GENERAL;
	sr_ret = sr_create_dir();
	sr_append(sr_ret, sr_create_str(ST_STR, asrv));
	*psr_res = sr_ret;
	ecm_free(asrv);

	return EDB_OK;
}

static edb_err_t
do_cmd_rename(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	return -ERR_EDB_NOTSUPPORTED;
}

static edb_err_t
do_cmd_ecx(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	const char	*cmd;

	if (election_state != MASTER_ELECTED || !IS_MASTER())
		return -ERR_EDB_NOTMASTER;

	cmd = sr_geti_str(sr_cmd, 1);

	EDBDDBG(DBG_CLIREQ, "CMD_GET_ECX: cmd:%s", ecm_safe_str(cmd));

	if (ecm_strcmp(cmd, "menu") == 0) {
		sr_t	*sr_info = sr_geti(sr_cmd, 2);

		*psr_res = process_menu(edbd_conn,
					sr_geti(sr_info, 0),
					sr_geti_int(sr_info, 1));
	}
	else if (ecm_strcmp(cmd, "banner") == 0)
		*psr_res = sr_dup(sr_eds_banner_img);
	else if (ecm_strcmp(cmd, "ecxup") == 0) {
		sr_t	*sr_ecx_state = sr_geti(sr_cmd, 2);
		*psr_res = process_ecxup(edbd_conn, sr_ecx_state);
	}
	else if (ecm_strcmp(cmd, "active_area") == 0)
		*psr_res = process_active_area(edbd_conn, sr_geti_str(sr_cmd, 2));
	else {
		sr_t	*sr_ecx_state = sr_geti(sr_cmd, 2);
		*psr_res = process_ecx(edbd_conn, sr_ecx_state);
	}
	return EDB_OK;
}

static edb_err_t
do_cmd_filecopy(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	ebc_ndid_t	src_ndid, dst_ndid;
	const char	*src_path, *dst_path;
	edb_fileopt_t	opt;

	src_ndid = sr_geti_int(sr_cmd, 1);
	src_path = sr_geti_str(sr_cmd, 2);
	dst_ndid = sr_geti_int(sr_cmd, 3);
	dst_path = sr_geti_str(sr_cmd, 4);
	opt = sr_geti_int(sr_cmd, 5);

	EDBDDBG(DBG_CLIREQ, "CMD_FILECOPY: src:%s, dest:%s",
		ebc_dbg_ndid(src_ndid),
		ebc_dbg_ndid(dst_ndid));
	
	*psr_res = NULL;
	return edbd_filecopy(src_ndid, src_path, dst_ndid, dst_path, opt);
}

static edb_err_t
do_cmd_fileremove(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	ebc_ndid_t	ndid;
	const char	*path;
	edb_fileopt_t	opt;

	ndid = sr_geti_int(sr_cmd, 1);
	path = sr_geti_str(sr_cmd, 2);
	opt = sr_geti_int(sr_cmd, 3);

	EDBDDBG(DBG_CLIREQ, "CMD_FILEREMOVE: %s", ebc_dbg_ndid(ndid));
	
	*psr_res = NULL;
	return edbd_fileremove(ndid, path, opt);
}

static edb_err_t
do_cmd_filemkdir(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	ebc_ndid_t	ndid;
	const char	*vpath;
	edb_fileopt_t	opt;

	ndid = sr_geti_int(sr_cmd, 1);
	vpath = sr_geti_str(sr_cmd, 2);
	opt = sr_geti_int(sr_cmd, 3);

	EDBDDBG(DBG_CLIREQ, "CMD_FILEMKDIR: %s:%s", ebc_dbg_ndid(ndid), ecm_safe_str(vpath));
	
	*psr_res = NULL;
	return edbd_filemkdir(ndid, vpath, opt);
}

static edb_err_t
do_cmd_fileexist(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	ebc_ndid_t	ndid;
	const char	*vpath;

	ndid = sr_geti_int(sr_cmd, 1);
	vpath = sr_geti_str(sr_cmd, 2);

	EDBDDBG(DBG_CLIREQ, "CMD_FILEEXIST: ndid:%s, vpath:%s",
		ebc_dbg_ndid(ndid), vpath);
	
	*psr_res = NULL;
	return edbd_fileexist(ndid, vpath);
}

static edb_err_t
do_cmd_file_open(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	ebc_ndid_t	dst_ndid;
	const char	*dst_path;
	ecm_uint32	flags;
	ecm_uint32	key;
	ecm_uint64	startoff;
	edb_err_t	err;

	dst_ndid = sr_geti_int(sr_cmd, 1);
	dst_path = sr_geti_str(sr_cmd, 2);
	flags = sr_geti_int(sr_cmd, 3);
	startoff = sr_geti_int(sr_cmd, 4);
	err = edbd_file_open(edbd_conn, dst_ndid, dst_path, flags, startoff, &key);
	if (err == EDB_OK)
		*psr_res = sr_create_int(ST_INT, key);
	return err;
}

static edb_err_t
do_cmd_file_close(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	ebc_ndid_t	dst_ndid;
	ecm_uint32	key;
	ECMBOOL		done;

	dst_ndid = sr_geti_int(sr_cmd, 1);
	key = sr_geti_int(sr_cmd, 2);
	done = sr_geti_bool(sr_cmd, 3);

	*psr_res = NULL;
	return edbd_file_close(edbd_conn, dst_ndid, key, done);
}

static edb_err_t
do_cmd_authuser(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	const char	*username, *passwd;
	char	*sessionid;
	edb_err_t	err;

	username = sr_geti_str(sr_cmd, 1);
	passwd = sr_geti_str(sr_cmd, 2);

	EDBDDBG(DBG_CLIREQ, "CMD_AUTHUSER: username:%s", ecm_safe_str(username));

	if ((err = edbd_auth_user(edbd_conn, username, passwd, &sessionid)) == EDB_OK)
		*psr_res = sr_set_val(sr_create(ST_STR), sr_val_str(sessionid));
	return err;
}

static edb_err_t
do_cmd_exec(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t	*sr_edexpr, *sr_cwd;
	sr_t	*sr_args;
	sr_t	*sr_res;
	const char	*edexpr;
	edb_err_t	err;

	edexpr = sr_geti_str(sr_cmd, 1);

	EDBDDBG(DBG_CLIREQ, "CMD_EXEC: %s", edexpr);

	sr_args = sr_geti(sr_cmd, 2);
	sr_edexpr = edl_get_edexpr(edexpr, NULL, NULL);
	if (sr_edexpr == NULL)
		return -ERR_EDB_INVALIDARG;
	sr_cwd = edbd_conn_getcwd(edbd_conn);
	if (sr_cwd == NULL) {
		sr_free(sr_edexpr);
		return -ERR_EDB_NOTEXIST;
	}

	conn_prepare_reaction(edbd_conn);
	if (!exec_edexpr(edbd_conn, sr_cwd, sr_args, NULL, sr_edexpr, &sr_res))
		err = -ERR_EDB_INVALIDARG;
	else {
		err = EDB_OK;
		if (sr_is_real(sr_res))
			*psr_res = sr_res;
		else {
			*psr_res = edbsr_dup(edbd_conn, sr_res);
			sr_free(sr_res);
		}
	}
	tree_unlock(sr_cwd, PIN_LOCK);
	conn_commit_reaction(edbd_conn);
	sr_free(sr_edexpr);
	return err;
}

static edb_err_t
do_cmd_execprocess(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	ebc_ndid_t	ndid;
	sr_t		*sr_exectx;

	ndid = sr_geti_int(sr_cmd, 1);
	sr_exectx = sr_geti(sr_cmd, 2);
	if (!edbd_run_process_sr(ndid, sr_exectx, psr_res))
		return -ERR_EDB_GENERAL;
	return EDB_OK;
}

static edb_err_t
do_cmd_master_election(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	*psr_res = NULL;
	return edbd_handover_master();
}

static edb_err_t
do_cmd_add_pathmon(edbd_conn_t edbd_conn, sr_t *sr_cmd)
{
	sr_t	*sr_LNP;
	sr_t	*sr_target;
	ebc_addr_t	addr;

	sr_LNP = sr_geti(sr_cmd, 1);
	sr_target = edbroot_get_from_cwd(edbd_conn, sr_LNP);
	if (sr_target == NULL)
		return -ERR_EDB_NOTEXIST;
	if (sr_is_vHMS(sr_target)) {
		edbroot_release(sr_target, ECM_TRUE);
		return -ERR_EDB_INVALIDARG;
	}
	addr.ndid = sr_geti_int(sr_cmd, 2);
	addr.mdid = sr_geti_int(sr_cmd, 3);
	addr.ptid = sr_geti_int(sr_cmd, 4);
	
	if (!edbd_add_pathnoti(edbd_conn, sr_target, &addr)) {
		edbroot_release(sr_target, ECM_TRUE);
		return -ERR_EDB_EXIST;
	}
	edbroot_release(sr_target, ECM_TRUE);
	return EDB_OK;
}

static edb_err_t
do_cmd_del_pathmon(edbd_conn_t edbd_conn, sr_t *sr_cmd)
{
	ebc_addr_t	addr;

	addr.ndid = sr_geti_int(sr_cmd, 1);
	addr.mdid = sr_geti_int(sr_cmd, 2);
	addr.ptid = sr_geti_int(sr_cmd, 3);

	edbd_del_pathnoti(edbd_conn, &addr);
	return EDB_OK;
}

#ifdef ECM_DEBUG

static edb_err_t
do_cmd_dbgset(sr_t *sr_cmd, sr_t **psr_res)
{
	const char	*modname, *dbgset;

	modname = sr_geti_str(sr_cmd, 1);
	dbgset = sr_geti_str(sr_cmd, 2);
	if (modname == NULL) {
		extern ECMBOOL	setup_debugset(const char *);
		setup_debugset(dbgset);
	}
	else {
		eds_mod_t	*mod;

		mod = eds_find_module(modname);
		if (mod == NULL)
			return -ERR_EDB_NOTEXIST;
		ecm_free(mod->dbgset);
		mod->dbgset = ecm_strdup(dbgset);
	}
	*psr_res = NULL;
	return EDB_OK;
}

#ifdef ECM_MTRACE

static void
do_cmd_mtrace(sr_t *sr_cmd, sr_t **psr_res)
{
	switch (sr_geti_int(sr_cmd, 0)) {
	case EDB_CMD_MTRACE_INFO: {
		ecm_memused_t	memused;

		ecm_get_memused(&memused);

		*psr_res = sr_create_dir();
		sr_append(*psr_res, sr_create_bool(ST_BOOL, ecm_is_mtraced()));
		sr_append(*psr_res, sr_create_int(ST_INT, memused.mem_used));
		sr_append(*psr_res, sr_create_int(ST_INT, memused.mem_used_per_thread));
		return;
	}
	case EDB_CMD_MTRACE_ON:
		ecm_mtrace(ECM_FALSE, sr_geti_int(sr_cmd, 1));
		return;
	case EDB_CMD_MTRACE_OFF:
		ecm_muntrace();
		return;
	case EDB_CMD_MTRACE_CLEAR:
		ecm_mtrace_clear();
		return;
	case EDB_CMD_MTRACE_REPORT:
		*psr_res = get_sr_mtraces();
		return;
	default:
		return;
	}
}

#endif

extern sr_t *get_sr_treelock_infos(const sr_t *);

static edb_err_t
do_cmd_treelock_info(sr_t *sr_cmd, sr_t **psr_res)
{
	sr_t	*sr_treelock_infos;

	sr_treelock_infos = get_sr_treelock_infos(NULL);
	if (sr_treelock_infos == NULL) {
		return -ERR_EDB_BUSY;
	}
	*psr_res = sr_treelock_infos;
	return EDB_OK;
}

#endif

edb_err_t
process_cmd(edbd_conn_t edbd_conn, sr_t *sr_cmd, sr_t **psr_res)
{
	int	cmd_type;
	edb_err_t	err = -ERR_EDB_INVALIDCMD;

	*psr_res = NULL;
	cmd_type = sr_geti_int(sr_cmd, 0) & ~EDB_CMD_FLAG_MASK;

	switch (cmd_type) {
	case EDB_CMD_CREATE:
		err = do_cmd_create(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_RENAME:
		err = do_cmd_rename(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_GET:
		err = do_cmd_get(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_SET:
		err = do_cmd_set(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_SET_SR:
		err = do_cmd_set_sr(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_DEL:
		err = do_cmd_del(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_XECREATE:
		err = do_cmd_xecreate(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_XEDELETE:
		err = do_cmd_xedelete(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_SNAPSHOT:
		err = do_cmd_snapshot(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_CD:
		err = do_cmd_cd(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_GET_MODINFOS:
		err = do_cmd_get_modinfos(edbd_conn, psr_res);
		break;
	case EDB_CMD_SHUTDOWN:
		err = do_cmd_shutdown(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_GET_TYPENAME:
		err = do_cmd_get_typename(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_GET_INHERITED_SRTS:
		err = do_cmd_get_inherited_srts(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_SEARCH_SRT:
		err = do_cmd_search_srt(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_GET_ASRV:
		err = do_cmd_get_asrv(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_CLOSE:
		err = do_cmd_close(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_ECX:
		err = do_cmd_ecx(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_FILECOPY:
		err = do_cmd_filecopy(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_FILEREMOVE:
		err = do_cmd_fileremove(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_FILEEXIST:
		err = do_cmd_fileexist(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_FILEMKDIR:
		err = do_cmd_filemkdir(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_FILE_OPEN:
		err = do_cmd_file_open(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_FILE_CLOSE:
		err = do_cmd_file_close(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_AUTHUSER:
		err = do_cmd_authuser(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_EXEC:
		err = do_cmd_exec(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_EXECPROCESS:
		err = do_cmd_execprocess(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_MASTER_ELECTION:
		err = do_cmd_master_election(edbd_conn, sr_cmd, psr_res);
		break;
	case EDB_CMD_ADD_PATHMON:
		err = do_cmd_add_pathmon(edbd_conn, sr_cmd);
		break;
	case EDB_CMD_DEL_PATHMON:
		err = do_cmd_del_pathmon(edbd_conn, sr_cmd);
		break;
#ifdef ECM_DEBUG
	case EDB_CMD_DBGSET:
		err = do_cmd_dbgset(sr_cmd, psr_res);
		break;
#ifdef ECM_MTRACE
	case EDB_CMD_MTRACE_INFO:
	case EDB_CMD_MTRACE_ON:
	case EDB_CMD_MTRACE_OFF:
	case EDB_CMD_MTRACE_CLEAR:
	case EDB_CMD_MTRACE_REPORT:
		do_cmd_mtrace(sr_cmd, psr_res);
		err = EDB_OK;
		break;
#endif
	case EDB_CMD_TREELOCK_INFO:
		err = do_cmd_treelock_info(sr_cmd, psr_res);
		break;
#endif
	default:
		ECMERR(("Invalid Command"));
		
	}

	return err;
}
